
import re
from os import path

from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.chrome.options import Options

from tools.verify import Verify
from tools.zsq import relations


class Web:
    """web自动化关键字类"""

    def __init__(self):
        self.driver: webdriver.Chrome = None
        # 使用字典保存关联的数据
        self.relation_dict = {}

    def open_browser(self, browser='gc'):
        """
        打开浏览器
        :param br: 默认使用谷歌浏览器
        :param browser: 浏览器类型：支持谷歌/火狐....
        :return:
        """
        if browser == 'ff':
            self.br = 'ff'
            self.driver = webdriver.Firefox()
        elif browser == 'ie':
            self.br = 'ie'
            self.driver = webdriver.Ie()
        elif browser == 'eg':
            self.br = 'eg'
            self.driver = webdriver.Edge()
        else:
            option = Options()
            # 去掉自动化标识
            option.add_experimental_option('excludeSwitches', ['enable-automation'])
            option.add_argument('--disable-blink-features=AutomationControlled')

            # 关掉密码弹窗
            prefs = {}
            prefs['credentials_enable_service'] = False
            prefs['profile.password_manager_enabled'] = False
            option.add_experimental_option('prefs', prefs)

            self.driver = webdriver.Chrome(options=option)

        # 添加隐式等待
        self.driver.implicitly_wait(15)
        # 最大化浏览器
        self.driver.maximize_window()

    def get_url(self, url=''):
        """
        打开被测地址
        :param url: 被测地址，支持完整写法或者仅域名或者IP的写法
        :return:
        """
        if url.startswith('http'):
            self.driver.get(url)
        else:
            self.driver.get('http://' + url)

    def __find_element(self, locator: str = ''):
        """
        统一定位方式
        :param locator: 元素定位器，同时支持xpath/css/id
        :return: 定位到的元素，如果没有就返回None
        """
        if locator is None or locator == '':
            return None
        # xpath通常以'/'开头，可能也会以'('开头:
        elif locator.startswith('/') or locator.startswith('('):
            element = self.driver.find_element('xpath', locator)
        elif locator.startswith('#') or locator.__contains__('>'):
            element = self.driver.find_element('css selector', locator)
        else:
            element = self.driver.find_element('id', locator)

        # 给操作的元素高亮显示
        if element:
            self.driver.execute_script("arguments[0].style.background = '#00ff50'", element)
        return element

    @relations
    def input(self, locator='', value=''):
        """
        文本输入
        :param locator: 元素定位
        :param value: 输入的内容
        :return:
        """
        element = self.__find_element(locator)
        # if value.endswith('.png') or value.endswith('.jpg'):
        #     value = path + 'lib\\' + value
        element.send_keys(value)

    def clear(self, locator):
        """清空输入框"""
        element = self.__find_element(locator)
        element.clear()

    def click(self, locator):
        """
        点击元素
        :param locator:
        :return:
        """
        element = self.__find_element(locator)
        element.click()

    def js_click(self, locator=''):
        """js点击"""
        element = self.__find_element(locator)
        self.driver.execute_script("arguments[0].click()", element)

    def try_clicks(self, locator=''):
        """点击"""
        try:
            self.driver.implicitly_wait(3)
            element = self.__find_element(locator)
            element.click()
        except Exception as e:
            print('尝试点击元素 %s 错误' % locator)
        finally:
            self.driver.implicitly_wait(10)

    def slide_12306(self):
        ele = self.__find_element('//*[@id="nc_1_n1z"]')

        # 要操作鼠标就要使用selenium 的 actionChains类
        action = ActionChains(self)
        # 鼠标按住滑块
        action.click_and_hold(ele)
        # 滑动的距离：300像素
        action.move_by_offset(300, 0)
        # 松开鼠标
        action.release()
        # 一定要记得加perform()，不然不生效！！！
        action.perform()

    def get_verfiy(self, locator):
        ele_img = self.__find_element(locator)
        ele_img.screenshot('verify.png')
        verify = Verify('testingzx', '1q2w3e4r.', '943050')
        ver = verify.get_verify('verify.png')
        self.relation_dict['verify'] = ver
        return ver



    def get_text(self, locator='', reg=''):
        """
        获取元素的文本
        :param locator:
        :param reg: 对文本进行正则处理
        :return:
        """
        element = self.__find_element(locator)
        text = element.text
        # 如果有正则，就按正则来处理
        if reg:
            text = re.findall(reg, text)
            if text:
                text = text[0]

        # 如果获取的属性可以是一个系统变量，则用{text}保存起来
        self.relation_dict['text'] = text
        return text

    @relations
    def save_params(self, name='', value=''):
        """
        把参数保存为你需要的名字
        :param name: 参数名
        :param value: 参数值
        :return:
        """
        self.relation_dict[name] = value
    #nxz 2024年7月25日16:34:14 add 获取元素的属性
    def get_attribute(self,locator,attr):
        attrstr = self.__find_element(locator).get_attribute(attr)
        return attrstr